﻿using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using Expressions.Compiler;
using Expressions.Compiler.Interfaces;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Expressions.Compiler.Internal;

namespace Tests
{
    /// <summary>
    ///This is a test class for TokenTest and is intended
    ///to contain all TokenTest Unit Tests
    ///</summary>
    [TestClass()]
    public class Test7__
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        private static Tokens Initialize(out Nonterminal G)
        {
            Terminal[] _ = { '(', '+', ')' };
            Tokens rules;
            G = "G";
            Nonterminal E = "E";
            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];
            rules = rule1 + rule2 + rule3;
            G.Definition = new Rules
            {
                () => rules
            };
            E.Definition = new Rules
            {
                () => '(',
                () => '+',
                () => ')'
            };
            return rules;
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_1()
        {
            Nonterminal G;
            Tokens target = Initialize(out G);

            G.Initialize();
            G.Validate();

            IEnumerator<Token> enumerator = target.Items.GetEnumerator();

            Parser input = "(+)";

            enumerator.MoveNext();
            Token token1 = enumerator.Current;
            bool rule1_result = token1.Entity.Parse(input) == true;

            enumerator.MoveNext();
            Token token2 = enumerator.Current;
            bool rule2_result = token2.Entity.Parse(input) == true;

            enumerator.MoveNext();
            Token token3 = enumerator.Current;
            bool rule3_result = token3.Entity.Parse(input) == true;

            bool expected = true;
            bool actual = rule1_result && rule2_result && rule3_result;

            bool rule123_result = target.Parse(input) == true;
            bool parse_result = G.Parse((Parser)"(+)");

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_2()
        {
            Nonterminal G;
            Tokens target = Initialize(out G);

            Parser input = "(+)";

            G.Initialize();
            G.Validate();

            G.Parse(input);

            bool expected = true;
            bool actual = input.Tree != null;

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_3()
        {
            Nonterminal G;
            Tokens target = Initialize(out G);

            G.Initialize();
            G.Validate();

            Parser input = "(+)";
            bool expected = true;
            bool actual = G.Parse(input) == true;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_4()
        {
            Nonterminal target = "G";
            target.Definition = new Rules
            {
                () => '\0'
            };

            target.Initialize();
            target.Validate();

            Entity token = target;
            string text = '\0'.ToString();
            bool expected = true;
            bool actual;
            actual = token.Parse((Parser)text);
            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_5()
        {
            Nonterminal G;
            Tokens target = Initialize(out G);

            G.Initialize();
            G.Validate();

            Parser input = "(+)";

            bool expected = true;
            bool actual = true;

            IEnumerator enumerator = ((IEnumerable)target.Items).GetEnumerator();
            while (enumerator.MoveNext())
            {
                Token token = (Token)enumerator.Current;
                if (!token.Entity.Parse(input))
                {
                    actual = false;
                    break;
                }
            }

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_6()
        {
            Terminal[] _ = { '(', '+', ')' };

            Nonterminal G = "G";
            Nonterminal E = "E";
            Tokens target = ((Rules.Definition)(() => new Tokens() { '(', '+', ')' }))();

            G.Definition = new Rules
            {
                () => target
            };

            E.Definition = new Rules
            {
                () => "class ",
                () => '+',
                () => '-'
            };

            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];

            target = rule1 + rule2 + rule3;

            G.Initialize();
            G.Validate();

            Parser input1 = "class ";
            Parser input2 = "+";
            Parser input3 = "?";

            Parser[] data = new Parser[] { input1, input2, input3 };

            Parser input = input1 + input2 + input3;

            bool expected = false;
            bool actual = true;

            int counter = 0;
            IEnumerator enumerator = ((IEnumerable)target.Items).GetEnumerator();
            while (enumerator.MoveNext())
            {
                Token token = (Token)enumerator.Current;
                if (!token.Entity.Parse(data[counter++]))
                {
                    actual = false;
                    break;
                }
            }

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_7()
        {
            Nonterminal G = "G";
            Nonterminal E = "E";
            Tokens target = ((Rules.Definition)(() => new Tokens { '(', '+', ')' }))();

            G.Definition = new Rules
            {
                () => target
            };

            E.Definition = new Rules
            {
                () => "class",
                () => '+',
                () => '-'
            };

            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];

            target = rule1 + rule2 + rule3;

            G.Initialize();
            G.Validate();

            Parser input = "class+?";

            bool expected = false;
            bool actual = target.Parse(input);

            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_8()
        {
            Rules.Definition expected = () => '(';

            Rules rules = new Rules
            {
                expected
            };

            IEnumerator enumerator = ((IEnumerable)rules).GetEnumerator();
            enumerator.MoveNext();

            Rules.Definition actual = ((Rule)enumerator.Current).Definition;

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_9()
        {
            Rules.Definition expected = () => '(';

            Rules rules = new Rules
            {
                expected
            };

            IEnumerator enumerator = ((IEnumerable)rules).GetEnumerator();
            enumerator.MoveNext();

            Rules.Definition actual = ((Rule)enumerator.Current).Definition;

            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_10()
        {
            Rule rule = (Rules.Definition)(() => null);

            Rules rules = new Rules
            {
                rule.Definition
            };

            IEnumerator enumerator = ((IEnumerable)rules).GetEnumerator();
            enumerator.MoveNext();

            bool expected = true;
            bool actual = (Rule)enumerator.Current == rule;

            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_11()
        {
            Nonterminal G = "G";
            Nonterminal E = "E";
            Tokens target = ((Rules.Definition)(() => new Tokens { '(', '+', ')' }))();

            G.Definition = new Rules
            {
                () => target
            };

            E.Definition = new Rules
            {
                () => "class",
                () => '+',
                () => '-'
            };

            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];

            target = rule1 + rule2 + rule3;

            Parser input = "lass+?";

            G.Initialize();
            G.Validate();

            bool expected = false;
            bool actual = target.Parse(input);

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_12()
        {
            Rules.Definition rule = () => null;

            bool expected = true;
            bool actual = null == rule();

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_13()
        {
            Nonterminal G = "G";
            Nonterminal E = "E";
            Tokens source = new Tokens() { };
            Tokens target = ((Rules.Definition)(() => new Tokens { '(', "+", ')' }))();

            G.Definition = new Rules
            {
                () => target
            };

            E.Definition = new Rules
            {
                () => "class",
                () => '+',
                () => '-'
            };

            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];

            target = rule1 + rule2 + rule3;

            G.Initialize();
            G.Validate();

            Parser input = "clas+?";

            bool expected = false;
            bool actual = target.Parse(input);

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_14()
        {
            Nonterminal G = "G";
            Nonterminal E = "E";
            Tokens target = ((Rules.Definition)(() => new Tokens { '(', '+', ')' }))();

            G.Definition = new Rules
            {
                () => target
            };

            E.Definition = new Rules
            {
                () => "class",
                () => '+',
                () => '-'
            };

            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];

            target = rule1 + rule2 + rule3;

            G.Initialize();
            G.Validate();

            Parser input = "classs+?";

            bool expected = false;
            bool actual = target.Parse(input);

            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_15()
        {
            Rules.Definition rule = () => null;

            Rules rules = new Rules
            {
                rule
            };

            IEnumerator<Rule> enumerator = (IEnumerator<Rule>)((IEnumerable)rules).GetEnumerator();
            enumerator.MoveNext();

            bool expected = true;
            bool actual = ((Rule)enumerator.Current).Definition == rule;

            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_16()
        {
            Rules.Definition expected = null;

            Rules.Definition empty = null;
            Rule actual = empty;

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_17()
        {
            Nonterminal G;
            Terminal[] _ = { '(', '+', ')' };
            Tokens target;

            G = "G";

            Nonterminal E = "E";

            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];
            target = rule1 + rule2 + rule3;

            Rule rule = (Rule)(() => target);

            G.Definition = new Rules
            {
                rule.Definition
            };

            E.Definition = new Rules
            {
                () => '(',
                () => '+',
                () => ')'
            };

            Parser input = "(+)";

            G.Initialize();
            G.Validate();

            bool expected = true;
            bool actual = G[rule.Definition].Definition == rule.Definition;

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_18()
        {
            Nonterminal G;
            Terminal[] _ = { '(', '+', ')' };

            Tokens target;

            G = "G";

            Nonterminal E = "E";

            Tokens rule1 = E[false];
            Tokens rule2 = E[false];
            Tokens rule3 = E[false];
            target = rule1 + rule2 + rule3;

            Rule rule = (Rule)(() => target);
            Rules rules = new Rules { rule.Definition };

            E.Definition = new Rules
            {
                () => '(',
                () => '+',
                () => ')',
            };

            G.Definition = rules;

            Parser input = "(+)";

            G.Initialize();
            G.Validate();

            G.Parse(input);

            List<IExpressionTree> children = new List<IExpressionTree>(((input.Tree) as ExpressionTree).Children);

            bool expected = true;
            bool actual = children.Count == 1;

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_19()
        {
            Nonterminal G;
            Terminal[] _ = { '(', '+', ')' };

            Tokens target = new Tokens { '(', '+', ')' };

            G = "G";

            Nonterminal E = "E";

            Tokens rule1 = '(';
            Tokens rule2 = '+';
            Tokens rule3 = ')';

            target = rule1 + rule2 + rule3;

            G.Definition = new Rules { () => target };

            E.Definition = new Rules
            {
                () => '(',
                () => '+',
                () => ')',
            };

            Parser input = "(+)";

            G.Initialize();
            G.Validate();

            bool expected = true;
            bool actual = G.Parse(input);

            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod(), Conditional("DEBUG")]
        public void Test7_20()
        {
            Parser input = "(+)";

            IExpressionTree root = input.Tree;

            bool expected = true;
            bool actual = root == null;

            Assert.AreEqual(expected, actual);
        }
    }
}
